// v11.v
// Verilog version, rewritten by Li Shen, Aug 2002
// Institute of Computing Technology, Chinese Academy of Sciences
// The original VHDL version is b11.vhd from Politecnico di Torino

module b11 (clock, reset, stbi, x_in, x_out);
input clock;
input reset;
input stbi;
input [5:0] x_in;
output [5:0] x_out;
/////
wire clock;
wire reset;
wire stbi;
wire [5:0] x_in;
reg [5:0] x_out;
/////
parameter s_reset=0, s_datain=1, s_spazio=2;
parameter s_mul=3, s_somma=4, s_rsum=5;
parameter s_rsot=6, s_compl=7, s_dataout=8;
reg [3:0] stato;
reg [5:0] r_in;
reg [5:0] cont;
reg [8:0] cont1; //signed
/////
always @(posedge clock)
begin
    if (reset)
    begin
	stato=s_reset;
	r_in=0;
	cont=0;
	cont1=0;
	x_out<=0;
    end
    else
    case (stato)
      s_reset:
      begin
	cont=0;
	r_in=x_in;
	x_out<=0;
	stato=s_datain;
      end
      s_datain:
      begin
	r_in=x_in;
	if (stbi)
	  stato=s_datain;
	else
	  stato=s_spazio;        
      end
      s_spazio:
	if (r_in==0 || r_in==63)
	begin
	  if (cont<25) cont=cont+1;
	  else	       cont=0;
	  cont1=r_in;
	  stato=s_dataout;
	end
	else if (r_in<=26) stato=s_mul;
	     else          stato=s_datain;
      s_mul:
      begin
	if (r_in & 1) cont1=cont<<1;
	else 	      cont1=cont;
	stato=s_somma;
      end
      s_somma:
	if ((r_in & 3)>>1)
        begin
	  cont1=r_in+cont1;
	  stato=s_rsum;
        end
	else
        begin
	  cont1=r_in-cont1;
	  stato=s_rsot;
        end
      s_rsum:
	if (!cont1[8] && cont1>26)
        begin
	  cont1=cont1-26;
	  stato=s_rsum;
        end
	else
	  stato=s_compl;
      s_rsot:
      begin
	if (!cont1[8] && cont1>63)
	begin
	  cont1=cont1+26;
	  stato=s_rsot;
	end
	else
	  stato=s_compl;
      end
      s_compl:
      begin
	if ((r_in>>2 & 3)==0)	        cont1=cont1 - 21;
	else if ((r_in>>2 & 3) == 1)	cont1=cont1 - 42;
	else if ((r_in>>2 & 3) == 2)	cont1=cont1 + 7;
	else				cont1=cont1 + 28;
	stato=s_dataout;
      end
      s_dataout:
      begin
	if (cont1[8]) //<0
	  x_out<= -cont1 & 63;
	else
	  x_out<= cont1 & 63;
	stato=s_datain;
      end
    endcase
end
endmodule
